iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
Software Development

一起看無間道學EdgeDB系列 第 10

[Day10] - 初始schema:人

  • 分享至 

  • xImage
  •  

從[Day10]~[Day13],我們將針對不同人時地事四個面向,建立初始schema。

Scalar types

PoliceRank

PoliceRank共有十七個階級,其中十五個階級為依據維基百科所定義。剩餘兩個階級分別為Protected(臥底)及Cadet(警校學生)。

由於階級是有限個數,適合使用extending Enum來建立PoliceRank

其中extending是EdgeDB中表現繼承(inheritance)的關鍵字。

scalar type PoliceRank extending enum<Protected, Cadet, PC, SPC, SGT, SSGT, PI, IP, SIP, CIP, SP, SSP, CSP, ACP, SACP, DCP, CP>;

GangsterRank

GangsterRank共有三個階級。

scalar type GangsterRank extending enum<Nobody, Leader, Boss>;

Abstract object types

Abstract object types不能直接被生成,但可以被其它object type所繼承。

Person

Person作為一個抽象的人物abstract object type,目的是希望能夠被真實世界的演員(Actor)以及劇中角色(Character)所extending。不論是演員或角色,有三個property是兩者皆具備的:

  • name property為一必填的property,為演員或劇中角色名字。
  • nickname property記錄綽號。
  • eng_name property記錄英文名字。
abstract type Person {
    required name: str;
    nickname: str;
    eng_name: str;
}

IsPolice

IsPolice有三個property

  • police_rank property代表警察官階,預設為警校學生(PoliceRank.Cadet)。object typepropertylink可以使用{}於其中添加一些額外的資訊或限制,例如給予預設值。
  • dept property代表警察部門。
  • is_officer property是一computed property(留意is_officer後使用的是:=,不是:),會根據police_rank是否高於PoliceRank.PI,來顯示truefalseenum的值是可以比較的,所以這邊可以使用>=)。
abstract type IsPolice {
    police_rank: PoliceRank {
        default:= PoliceRank.Cadet;
    };
    dept: str;
    is_officer:= .police_rank >= PoliceRank.PI;
}

computed property或link不必預先定義於schema,而可以根據某些條件來動態計算。例如這邊就用來動態計算警察的官階,是否高於PoliceRank.PI這個階級。由於computed是由已知資訊所計算而來,所以EdgeDB可以推斷出型別,無須特別指定。

IsGangster

IsGangster有一個property及一個link

  • gangster_rank property代表黑社會階級,預設為小弟(GangsterRank.Nobody)。
  • gangster_boss link代表此角色的老大。
abstract type IsGangster {
    gangster_rank: GangsterRank {
        default:= GangsterRank.Nobody;
    };
    gangster_boss: GangsterBoss;
}

IsSpy

EdgeDB具有多重繼承的特色,所以IsSpy可以同時extending IsPoliceIsGangster用來表示臥底。

abstract type IsSpy extending IsPolice, IsGangster;

Object types

Character

Character extending Person用來表示劇中角色,有一個property與兩個link

  • classic_lines property為一array<str>,用來記錄角色於劇中的名言。
  • lover link為劇中角色的戀人。
  • actors multi link為飾演劇中角色的演員(使用multi,因為一個角色可能由一個以上演員詮釋)。
type Character extending Person {
    classic_lines: array<str>;
    lover: Character;
    multi actors: Actor;
}

Actor

Actor extending Person用來表示演員。

type Actor extending Person;

Police

Police同時extending CharacterIsPolice用來表示警察。

type Police extending Character, IsPolice;

Gangster

Gangster同時extending CharacterIsGangster用來表示黑社會。

type Gangster extending Character, IsGangster;

GangsterBoss

GangsterBoss extending Gangster而來。

type GangsterBoss extending Gangster {
    overloaded gangster_rank: GangsterRank {
        default:= GangsterRank.Boss;
        constraint expression on (__subject__ = GangsterRank.Boss);
    };

    # excluding self
    constraint expression on (__subject__ != .gangster_boss) { 
        errmessage := "The boss can't be his/her own boss.";
    }
}

當想要針對繼承而來的propertylink進行更嚴格限制時,需要使用overloaded。請留意,overloaded只能進行更嚴格的限制,無法放鬆。

由於GangsterBoss也算是Gangster,只不過其gangster_rank位階較其它黑社會成員高,所以可以使用overloaded針對gangster_rank加上兩個限制:

  • 預設其gangster_rankGangsterRank.Boss

    default:= GangsterRank.Boss;
    
  • 無論是insertupdate GangsterBoss,其gangster_rank都只能指定為GangsterRank.Boss

    constraint expression on (__subject__ = GangsterRank.Boss);
    

    constraint expression on可接受一個expression來返回truefalse,如果返回的是true的話,才能允許相關操作。而__subject__代表此處將受限制的值(一個GangsterRank scalar)。

此外,我們針對GangsterBoss這個object type也加上一個constraint來限制自己不能是自己的gangster_boss。其中:

  • .gangster_boss.代表引用的是自身的gangster_boss property(定義於Gangster中)。
  • __subject__則代表自己(一個GangsterBoss object)。
  • errmessage可以指定於insertupdate發生錯誤時,所顯示的錯誤訊息。
constraint expression on (__subject__ != .gangster_boss) { 
    errmessage := "The boss can't be his/her own boss.";
}

PoliceSpy

PoliceSpy同時extending CharacterIsSpy,為警方派至黑社會之臥底。

type PoliceSpy extending Character, IsSpy;

GangsterSpy

GangsterSpy同時extending CharacterIsSpy,為黑社會派至警方之臥底。

type GangsterSpy extending Character, IsSpy;

參考資料

無間EdgeDB初始schema:人


上一篇
[Day09] - EdgeQL牛刀小試
下一篇
[Day11] - 初始schema:時
系列文
一起看無間道學EdgeDB30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言